#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <iostream>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    ui->download_progressBar->hide();
    open_flag = 0;
    start_flag = 0;
    packet_id = 0;
    timer.start(1000);
    connect(&timer, SIGNAL(timeout()), this, SLOT(timerOut_slot()));
    connect(&serial, SIGNAL(readyRead()), this, SLOT(read_serial_slot()));

    flag = 0;
    download_ok = 0;
    /* =1无心跳 */
    HeartBeat = 1;

    /* 样式 */
//    ui->Dim_Slider->setStyleSheet("QSlider::groove{border: 1px solid #999999;height: 8px;background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #B1B1B1, stop:1 #c4c4c4);margin: 2px 0;}");
//    ui->Dim_Slider->setStyleSheet("QSlider::handle{background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #b4b4b4, stop:1 #8f8f8f);border: 1px solid #5c5c5c;width: 18px;margin: -2px 0; border-radius: 3px;}");

//    ui->Dim_Slider->setStyleSheet(

//                "QSlider::groove:horizontal {                                "
//                "     border: 1px solid #999999;                             "
//                "     height: 2px;                                           "
//                "     margin: 0px 0;                                         "
//                "     left: 12px; right: 12px;                               "
//                " }                                                          "
//                "QSlider::handle:horizontal {                                "
//                "     border: 1px solid #5c5c5c;                             "
//                " border-image:url(image/skin2/Toolsicon/volumnslider.png);"
//                "     width: 18px;                                           "
//                "     margin: -7px -7px -7px -7px;                           "
//                " }                                                          "
//                "                                                            "
//                "QSlider::sub-page:horizontal{                               "
//                " background: qlineargradient(spread:pad, x1:0, y1:1, x2:0, y2:0, stop:0 rgba(27, 5, 27, 255), stop:0.25 rgba(99, 20, 102, 255), stop:0.5 rgba(154, 30, 158, 255), stop:1 rgba(173, 57, 176, 255));"
//                "}                                                           "
//                "QSlider::add-page:horizontal{                               "
//                " background-image:url(image/skin2/Toolsicon/volumn.png)   "
//                "}"
//                );
    ui->Dim_Slider->setStyleSheet(
                "QSlider::add-page:Horizontal"
                    "{     "
                        "background-color: rgb(87, 97, 106);"
                        "height:4px;"
                    "}"
                    "QSlider::sub-page:Horizontal "
                    "{"
                    "    background-color:qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(231,80,229, 255), stop:1 rgba(0,000,255, 255));"
                    "    height:4px;"
                    " }"
                    "QSlider::groove:Horizontal "
                    "{"
                    "    background:transparent;"
                    "    height:6px;"
                    "}"
                    "QSlider::handle:Horizontal "
                    "{"
                    "    height: 20px;"
                    "    width:60px;"
                    "    border-image: url(../images/ic_music_thumb2.png);"
                    "   margin: -8 0px; "
                    "}"

                );

}

MainWindow::~MainWindow()
{
    delete ui;
}

/* 打开串口 */
void MainWindow::on_serial_open_pushButton_clicked()
{
    if(open_flag == 0)
    {
        serial.setPortName(ui->serial_number_comboBox->currentText());
        serial.setBaudRate(ui->baud_rate_comboBox->currentText().toInt());
        switch(ui->parity_bit_comboBox->currentIndex())
        {
            case 0:
                serial.setParity(QSerialPort::NoParity); break;
            case 1:
                serial.setParity(QSerialPort::OddParity); break;
            case 2:
                serial.setParity(QSerialPort::EvenParity); break;
            case 3:
                serial.setParity(QSerialPort::MarkParity); break;
            case 4:
                serial.setParity(QSerialPort::SpaceParity); break;
            default:
                break;
        }
        switch(ui->data_bit_comboBox->currentIndex())
        {
            case  0:
                serial.setDataBits(QSerialPort::Data5); break;
            case  1:
                serial.setDataBits(QSerialPort::Data6); break;
            case  2:
                serial.setDataBits(QSerialPort::Data7); break;
            case  3:
                serial.setDataBits(QSerialPort::Data8); break;
            default:
                break;
        }
        switch(ui->stop_bit_comboBox->currentIndex())
        {
        case  0:
            serial.setStopBits(QSerialPort::OneStop); break;
        case  1:
            serial.setStopBits(QSerialPort::OneAndHalfStop); break;
        case  2:
            serial.setStopBits(QSerialPort::TwoStop); break;
        default:
            break;
        }
        serial.setFlowControl(QSerialPort::NoFlowControl);
        if(serial.open(QIODevice::ReadWrite) == true)
        {
            open_flag = 1;
            ui->serial_open_pushButton->setText(QString("关闭"));
            qDebug()<<"open success";
        }
        else
        {
            QMessageBox::warning(NULL, "warning", "串口不存在或者被其它应用程序占用！", "确定");
            qDebug()<<"open failed";
        }
    }
    else
    {
        serial.close();
        ui->serial_open_pushButton->setText(QString("打开"));
        open_flag = 0;
        qDebug()<<"close success";
    }
}

/* 定时器 */
void MainWindow::timerOut_slot(void)
{
    QStringList serial_Name_temp_list;

    if(open_flag == 1)
    {
        if(download_ok == 1)
        {
            /* 心跳 */
            unsigned char buf[10] = {0xEA, 0xEB, 0xEE, 0x04, 0x00, 0x06, 0x00, 0x00, 0x0D, 0x0A};
            serial_write(buf, 10);
            HeartBeat++;
            if(HeartBeat > 3)
            {
                /* 离线 */
                ui->label_15->setText("离线");
            }
            else
            {
                /* 在线 */
                ui->label_15->setText("在线");
            }
        }
        else
        {
            return;
        }
    }
    else
    {
        foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
        {
            serial_Name_temp_list << info.portName();
        }

        if(serial_Name_temp_list != serial_Name_list)
        {
            ui->serial_number_comboBox->clear();
            serial_Name_list = serial_Name_temp_list;
            ui->serial_number_comboBox->addItems(serial_Name_list);
        }
    }
}

/* 打开文件 */
void MainWindow::on_open_file_pushButton_clicked()
{
    QString path = QFileDialog::getOpenFileName(this, tr("Open File"), ".", tr("Bin Files(*.bin)"));
    if(path.isNull())
        return;

    ui->file_name_lineEdit->setText(path);
    QFile file(path);
    file.open(QIODevice::ReadWrite);
    QByteArray array = file.readAll();
    file_len = array.size();
    tx_data = array.data();
    write_index = 0;
    ui->download_progressBar->setValue(write_index/file_len);
}

/* 烧录 */
void MainWindow::on_download_pushButton_clicked()
{
    /* 烧录之前必须打开串口 */
    if(open_flag == 0)
    {
        QMessageBox::warning(NULL, "warning", "请打开串口！", "确定");
        return;
    }

    /* 烧录之前必须选择烧录文件 */
    if(ui->file_name_lineEdit->text().isEmpty())
    {
        QMessageBox::warning(NULL, "warning", "请选择需要烧录的文件！", "确定");
        return;
    }

    /* 烧录按钮变灰 */
    ui->download_pushButton->setEnabled(false);

    /* 显示进度条 */
    ui->download_progressBar->show();
    ui->download_progressBar->setValue(0);

    /* 写入的字节偏移量为0 */
    write_index = 0;

    /* 发送进入bootloader命令 */
    send_bootloader();

    /* 刷机开始 */
    start_flag = 1;
    download_ok = 0;
}

/* 串口写入函数 */
void MainWindow::serial_write(unsigned char *buf, int len)
{
    packet_id++;
    if(packet_id == 63)
        packet_id = 0;

    buf[4] = packet_id;
    printf("write_serial_%d[", len);
    for(int i = 0; i < len; i++)
        printf("%0.2x ", buf[i]);
    printf("]\n");
    std::cout.flush();

    serial.write((const char *)buf, len);
}


/* 发送bootloader */
void MainWindow::send_bootloader(void)
{
    /* 进入BootLoader */
    unsigned char buf[10] = {0xEA, 0xEB, 0xEE, 0x04, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0A};

    serial_write(buf, 10);
}

/* 串口接收槽函数 */
void MainWindow::read_serial_slot(void)
{
    QByteArray read_array;
    char *rx_data;
    int len;

    read_array = serial.readAll();
    rx_data = read_array.data();
    len = read_array.size();

    if(start_flag == 0)
        return;

    /* 校验命令 */
    if(check_cmd((unsigned char *)rx_data, len) == 0)
        return;

    int protocol;
    protocol = rx_data[5];
    unsigned char buf[50] = {0xEA, 0xEB, 0xEE, 0x2C ,0x00, 0x02, 0x00, 0x00};
    uint16_t CheckSum = 0;

    switch(protocol)
    {
        case 0:
            if(check_ack((unsigned char *)rx_data) == 0)
                return;
            break;

        case 1:
//            send_download();

            write_index = 0;
            buf[48] = 0x0D;
            buf[49] = 0x0A;
            buf[8] = write_index / 256;
            buf[9] = write_index % 256;
            memcpy(buf + 10, tx_data + write_index, 36);
            for(int j = 0; j < 36; j++)
            {
                CheckSum +=  buf[10 + j];
            }
            buf[46] = CheckSum / 256;
            buf[47] = CheckSum % 256;
            serial.write((const char *)buf, 50);
            break;

        case 2:
            write_index+=36;
            if(write_index <= file_len)
                ui->download_progressBar->setValue(write_index*100/file_len);
            else
                ui->download_progressBar->setValue(100);

            if(write_index < file_len)
            {
                int tx_len;

                if(write_index+36>file_len)
                {
                    tx_len = file_len-write_index;
                    buf[3] = 8 + tx_len;
                }
                else
                    tx_len = 36;

                buf[12+tx_len] = 0x0D;
                buf[13+tx_len] = 0x0A;
                buf[8] = write_index / 256;
                buf[9] = write_index % 256;
                memcpy(buf + 10, tx_data + write_index, tx_len);
                for(int j = 0; j < tx_len; j++)
                {
                    CheckSum +=  buf[10 + j];
                }
                buf[10+tx_len] = CheckSum / 256;
                buf[11+tx_len] = CheckSum % 256;

                serial.write((const char *)buf, 14+tx_len);
            }
            else
            {
                /* 启动APP */
                unsigned char buf1[10] = {0xEA, 0xEB, 0xEE, 0x04, 0x00, 0x03, 0x00, 0x00, 0x0D, 0x0A};
                serial.write((const char *)buf1, 10);
            }
            break;

        case 3:
            start_flag = 0;
            write_index = 0;
            ui->download_progressBar->setValue(0);
            ui->download_progressBar->hide();
            QMessageBox::information(NULL, "warning", "烧录成功！", "确定");
            ui->download_pushButton->setEnabled(true);
            download_ok = 1;
            break;

            /* 心跳回复 */
        case 6:
            HeartBeat = 0;

            /* 控制器上报的参数 */
        case 7:
            ui->label_8->setText(QString::number(rx_data[6] * 256 + rx_data[7]));
            ui->label_9->setText(QString::number(rx_data[8] * 256 + rx_data[9]));
            ui->label_10->setText(QString::number(rx_data[10] * 256 + rx_data[11]));
        default:
            break;
    }
}

/* 校验cmd */
int MainWindow::check_cmd(unsigned char *buf, int len)
{
    int flag = 0;

    printf("read_serial_%d[", len);
    for(int i = 0; i < len; i++)
        printf("%0.2x ", buf[i]&0xFF);
    printf("]\n");
    std::cout.flush();

    if(buf[0] == 0xEA && buf[1] == 0xEB && buf[2] == 0xEE)
    {
        if(buf[3] == len - 6)
        {
            if(buf[len-2] == 0x0D && buf[len-1] == 0x0A)
            {
                flag = 1;
            }
        }
    }

    if(flag == 0)
    {
        start_flag = 0;
        write_index = 0;
        ui->download_progressBar->setValue(0);
        ui->download_progressBar->hide();
        QMessageBox::warning(NULL, "warning", "烧录失败！", "确定");
        ui->download_pushButton->setEnabled(true);
        return 0;
    }

    return 1;
}


/* 校验ack */
int MainWindow::check_ack(unsigned char *buf)
{
    int flag = 0;

    if((buf[4]&0x3F) == packet_id)
        flag = 1;

    if(flag == 0)
    {
        start_flag = 0;
        write_index = 0;
        ui->download_progressBar->setValue(0);
        ui->download_progressBar->hide();
        QMessageBox::warning(NULL, "warning", "烧录失败！", "确定");
        ui->download_pushButton->setEnabled(true);
        return 0;
    }

    return 1;
}

/* 松开Slider */
void MainWindow::on_Dim_Slider_sliderReleased()
{
    uint8_t value;
    value = ui->Dim_Slider->value();

    QByteArray data(1, value);
    serial.write(data);
    qDebug() << value;
}

/* Slider值变化 */
void MainWindow::on_Dim_Slider_valueChanged(int value)
{
    ui->Dim_Value_label->setText(QString::number(value));
}

/* 开灯 */
void MainWindow::on_Turn_On_Button_clicked()
{
    if(flag == 1)
    {
        QByteArray data(1, 101);
        serial.write(data);
    }
}

/* 关灯 */
void MainWindow::on_Turn_Off_Button_clicked()
{
    if(flag == 1)
    {
        QByteArray data(1, 102);
        serial.write(data);
    }
}

/* 设置ID和Power */
void MainWindow::on_Set_ID_Power_pushButton_clicked()
{
    uint16_t id = 0;
    uint16_t power = 0;
    unsigned char buf1[12] = {0xEA, 0xEB, 0xEE, 0x04, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0A};

    id = ui->spinBox->value();
    power = ui->lineEdit->text().toInt();

    buf1[6] = id / 256;
    buf1[7] = id % 256;

    buf1[8] = power / 256;
    buf1[9] = power % 256;

    serial.write((const char *)buf1, 12);

    qDebug() << id;
    qDebug() << power;
}
